package blacklist

import (
	"fmt"
	"strings"

	"github.com/cnssl/apps/tools/windows-root-fixer/internal/audit"
	"github.com/cnssl/apps/tools/windows-root-fixer/internal/store"
)

// Processor 黑名单处理器
type Processor struct {
	logger             *audit.Logger
	preferIntermediate bool
	dryRun             bool
}

// NewProcessor 创建新的黑名单处理器
func NewProcessor(logger *audit.Logger, preferIntermediate, dryRun bool) *Processor {
	return &Processor{
		logger:             logger,
		preferIntermediate: preferIntermediate,
		dryRun:             dryRun,
	}
}

// Process 处理黑名单中的证书
func (p *Processor) Process(thumbprints []string) error {
	rollbackID := audit.GenerateRollbackID()
	fmt.Printf("开始处理黑名单 (回滚 ID: %s)\n", rollbackID)

	for _, thumbprint := range thumbprints {
		// 标准化指纹（去空格、转大写）
		thumbprint = normalizeThumbprint(thumbprint)

		if err := p.processOne(thumbprint, rollbackID); err != nil {
			fmt.Printf("警告: 处理证书 %s 失败: %v\n", thumbprint, err)
			continue
		}
	}

	fmt.Println("黑名单处理完成")
	return nil
}

// processOne 处理单个证书
func (p *Processor) processOne(thumbprint, rollbackID string) error {
	// 按优先级搜索证书
	var cert *store.Certificate
	var foundStore store.StoreName
	var err error

	// 1. 优先在中级 CA 存储中查找
	if p.preferIntermediate {
		cert, err = p.findInStore(thumbprint, store.StoreCA)
		if err == nil && cert != nil {
			foundStore = store.StoreCA
		}
	}

	// 2. 如果没找到，在根存储中查找
	if cert == nil {
		cert, err = p.findInStore(thumbprint, store.StoreRoot)
		if err == nil && cert != nil {
			foundStore = store.StoreRoot
		}
	}

	// 3. 如果都没找到，报告错误
	if cert == nil {
		return fmt.Errorf("未找到证书: %s", thumbprint)
	}

	// 4. 移动到 Disallowed 存储
	if p.dryRun {
		fmt.Printf("[演练] 将 %s 从 %s 移动到 Disallowed\n", thumbprint, foundStore)
		fmt.Printf("  Subject: %s\n", cert.Subject)
		fmt.Printf("  Issuer: %s\n", cert.Issuer)
	} else {
		if err := store.MoveCertificate(cert, foundStore, store.StoreDisallowed); err != nil {
			return fmt.Errorf("移动证书失败: %w", err)
		}

		// 记录审计日志
		p.logger.Log(audit.AuditEntry{
			Operation:    "move",
			Thumbprint:   thumbprint,
			Subject:      cert.Subject,
			Issuer:       cert.Issuer,
			SerialNumber: cert.SerialNumber,
			SourceStore:  string(foundStore),
			TargetStore:  string(store.StoreDisallowed),
			RollbackID:   rollbackID,
			Success:      true,
		})

		fmt.Printf("已将证书 %s 移动到 Disallowed\n", thumbprint)
	}

	return nil
}

// findInStore 在指定存储中查找证书
func (p *Processor) findInStore(thumbprint string, storeName store.StoreName) (*store.Certificate, error) {
	st, err := store.OpenStore(storeName)
	if err != nil {
		return nil, err
	}
	defer st.Close()

	return st.FindByThumbprint(thumbprint)
}

// normalizeThumbprint 标准化证书指纹（去空格、转大写）
func normalizeThumbprint(thumbprint string) string {
	thumbprint = strings.ReplaceAll(thumbprint, " ", "")
	thumbprint = strings.ToUpper(thumbprint)
	return thumbprint
}
